﻿using System;
using System.Collections.Generic;
using Gp.Scripts.Data;
using Gp.Scripts.Data.Skills;
using Gp.Scripts.Core;

namespace Gp.Scripts.Core {
    public static class AttackRuleChain {
        #region Data Init

        public static IRuleGroup<AttackActionRequest> AtkRuleChain(this IRuleGroup<AttackActionRequest> group) {
            return group
                    // .HelpChain("压制点数", SuppressPointBonus, SpCondition)
                    // .HelpChain("特殊效果：抗性", ResistivityRule, ResistivityRuleCondition)
                    // .HelpChain("弹幕：护甲伤害减半", BarrageBonus, BarrageJudge)
                    // .HelpChain("穿甲弹: 护甲伤害50%", ArmorPiercingBonus, ArmorPiercingJudge)
                    // .HelpChain("分解立场：护甲伤害翻倍", ArmorDamageBonus, ArmorDamageJudge)
                    // .RuleChain(new BarrierRuleWrapper().Build())
                    // .RuleChain(new DodgeRuleWrapper().Build())
                    // .RuleChain(new ShieldPenetrateRuleWrapper().Build())
                ;
        }

        private static IEnumerable<KeyValuePair<object, ModifierValue>> ArmorPiercingBonus(AttackActionRequest request) {
            yield return new KeyValuePair<object, ModifierValue>(SkillField.Damage, ModifierValue.Percentage(50));
        }

        private static bool ArmorPiercingJudge(AttackActionRequest arg) {
            return arg.Tags.Contains(SkillTags.ArmorPiercing) && arg.Target.ComEquip.HasArmor();
        }

        private static IRuleGroup<AttackActionRequest> HelpChain(this IRuleGroup<AttackActionRequest> group, string name,
            WeakRule<AttackActionRequest> bonus, Func<AttackActionRequest, bool> judge) {
            return group.RuleChain(new WeakRuleWrapper<AttackActionRequest>(name, bonus, judge));
        }

        #endregion


        #region Rule Chain

        private static IEnumerable<KeyValuePair<object, ModifierValue>> ArmorDamageBonus(AttackActionRequest request) {
            return new Dictionary<object, ModifierValue>(0) {
                {SkillField.Damage, new ModifierValue(0, 100)}
            };
        }


        private static bool ArmorDamageJudge(AttackActionRequest arg) {
            // 有护甲
            return arg.Tags.Contains(SkillTags.DissolveField) && arg.Target.ComEquip.HasArmor();
        }


        private static IEnumerable<KeyValuePair<object, ModifierValue>> BarrageBonus(AttackActionRequest request) {
            // 对护甲伤害减少50%
            return new Dictionary<object, ModifierValue>() {
                {SkillField.Damage, new ModifierValue(0, -50)}
            };
        }


        private static bool BarrageJudge(AttackActionRequest arg) {
            // 并且单位装备护甲
            return arg.Tags.Contains(SkillTags.Barrage) && arg.Target.ComEquip.HasArmor();
        }


        private static bool ResistivityRuleCondition(AttackActionRequest arg) {
            // return arg.Target.ComBuff.HasBuff<ResistivityEffect>();
            return false;
        }


        public static IEnumerable<KeyValuePair<object, ModifierValue>> ResistivityRule(AttackActionRequest request) {
            // 消耗buff
            // request.BuffConsume.Add(request.Target.ComBuff.GetBuff<ResistivityEffect>());

            // 伤害减少50%
            return new Dictionary<object, ModifierValue>(1) {{SkillField.Damage, new ModifierValue(-50)}};
        }


        // /// <summary>
        // /// 压制点加成触发条件：攻击单位与受击单位不同侧，并且攻击方压制点差值大于0
        // /// </summary>
        // /// <param name="args"></param>
        // /// <returns></returns>
        // private static bool SpCondition(AttackActionRequest args) {
        //     var dic = CellGridSystem.Instance.CellGridModel.Container;
        //     return args.Source.Side != args.Target.Side && dic.GetDelta(args.Source.Side) > 0;
        // }
        //
        //
        // /// <summary>
        // /// 压制点增长规则。当玩家的压制点数-敌人的压制点数的差为正数时，差值每有1点，玩家方就获得1%的伤害加成，若为负数，则插值每有1点，敌人造成的伤害获得1%的加成。
        // /// </summary>
        // private static IEnumerable<KeyValuePair<object, ModifierValue>> SuppressPointBonus(AttackActionRequest args) {
        //     var dic = CellGridSystem.Instance.CellGridModel.Container;
        //     var delta = dic.GetDelta(args.Source.Side);
        //     // 每点差值，伤害加成1%
        //     yield return 
        //         new KeyValuePair<object, ModifierValue>(SkillField.Damage, new ModifierValue(0, delta * .01f));
        // }

        #endregion
    }
}